'''
Created on Jun 26, 2011

@author: User
'''
import cliques.mdp.offlineLimitedSampling
import cliques.mdp.limitedSampling
import cliques.mdp.dfsMdp
from cliques.potentialCliques import potentialCliques

class SubsetState(cliques.mdp.dfsMdp.dfsState):
    '''
    A dfs state that only allows actions according to the clique* heuristic.
    '''
    def __init__(self,pcdb,g):
        cliques.mdp.dfsMdp.dfsState.__init__(self,pcdb, g)
    def actions(self):
        big_set = set()
        for kPc in self.pcdb:
            if self.pcdb.max_core==len(kPc.core):
                for item in kPc.gcn:
                    big_set.add(item)
        
        return list(big_set) # Make actions unique        


class CliqueStarTieBreaker(cliques.mdp.offlineLimitedSampling.OfflineLimitedSampling):
    ''' RClique* variant that limits the allowed actions to only select the highest potential clique neighbors '''
    def __init__(self, k, edge_prob, num_of_nodes):
        cliques.mdp.offlineLimitedSampling.OfflineLimitedSampling.__init__(self,k,edge_prob,num_of_nodes)
    
    def create_state(self,pcdb, g):
        return SubsetState(pcdb,g)
    
    def create_state_0(self, ckg, generated):
        return SubsetState(potentialCliques(self.k, self.search.pcdb),\
                             len(ckg) - len(generated))
        
        
class CliqueStarTieBreakerUniform(cliques.mdp.limitedSampling.LimitedSampling):
    ''' RClique* variant that limits the allowed actions to only select the highest potential clique neighbors '''
    def __init__(self, k, edge_prob, num_of_nodes):
        cliques.mdp.limitedSampling.LimitedSampling.__init__(self,k,edge_prob,num_of_nodes)
    
    def create_state(self,pcdb, g):
        return SubsetState(pcdb,g)
    
    def create_state_0(self, ckg, generated):
        return SubsetState(potentialCliques(self.k, self.search.pcdb),\
                             len(ckg) - len(generated)) 